﻿using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Gma.UserActivityMonitor;
using Meridian.Helpers;
using VkApi;
using Application = System.Windows.Application;
using Clipboard = System.Windows.Clipboard;
using DataFormats = System.Windows.DataFormats;
using DataObject = System.Windows.DataObject;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MessageBox = System.Windows.MessageBox;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;

namespace Meridian.Views
{
    /// <summary>
    /// Interaction logic for MainView.xaml
    /// </summary>
    public partial class MainView : Window
    {
        private IntPtr handle;
        //private readonly DispatcherTimer messagesCheckTimer;
        private MiniView miniView;

        public MainView()
        {
            InitializeComponent();

            this.DataContext = App.ViewModel;
            App.Player = this.MediaElement;

            UsernameTextBlock.MouseLeftButtonDown += (s, e) => App.ViewModel.Login();

            MyAudioList.MouseDoubleClick += (s, e) =>
                                                {
                                                    if (MyAudioList.SelectedIndex != -1)
                                                    {
                                                        App.ViewModel.IsPlayingFromSearch = false;
                                                        App.ViewModel.PlayAudio((VkAudio)MyAudioList.SelectedItem);
                                                    }
                                                };

            SearchList.MouseDoubleClick += (s, e) =>
            {
                if (SearchList.SelectedIndex != -1)
                {
                    App.ViewModel.IsPlayingFromSearch = true;
                    App.ViewModel.PlayAudio((VkAudio)SearchList.SelectedItem);
                }
            };

            MyAudioList.KeyDown += (s, e) =>
            {
                if (e.Key == Key.Enter && MyAudioList.SelectedIndex != -1)
                {
                    App.ViewModel.IsPlayingFromSearch = false;
                    App.ViewModel.PlayAudio((VkAudio)MyAudioList.SelectedItem);
                }
            };

            SearchList.KeyDown += (s, e) =>
            {
                if (e.Key == Key.Enter && SearchList.SelectedIndex != -1)
                {
                    App.ViewModel.IsPlayingFromSearch = true;
                    App.ViewModel.PlayAudio((VkAudio)SearchList.SelectedItem);
                }
            };

            App.ViewModel.PropertyChanged += (s, e) =>
                                                 {
                                                     switch (e.PropertyName)
                                                     {
                                                         case "IsPlaying":
                                                             if (App.ViewModel.IsPlaying)
                                                                 ThumbPlayButton.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Meridian;component/Resources/Images/pause_thumb.png"));
                                                             else
                                                                 ThumbPlayButton.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Meridian;component/Resources/Images/play_thumb.png"));
                                                             break;
                                                         case "Shuffle":
                                                             if (App.ViewModel.Shuffle)
                                                                 ThumbShuffleButton.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Meridian;component/Resources/Images/shuffle_icon_thumb.png"));
                                                             else
                                                                 ThumbShuffleButton.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Meridian;component/Resources/Images/shuffle_disabled_icon_thumb.png"));
                                                             break;
                                                     }
                                                 };

            //messagesCheckTimer = new DispatcherTimer();
            //messagesCheckTimer.Interval = TimeSpan.FromSeconds(20);
            //messagesCheckTimer.Tick += MessagesCheckTimerTick;
            //messagesCheckTimer.Start();

            HookManager.KeyDown += HookManagerKeyDown;

            ShuffleButton.IsChecked = App.Settings.Shuffle;
            App.ViewModel.Volume = (int)(App.Settings.Volume * 100);
            App.ViewModel.Login();


            MediaElement.BufferingEnded += (s, e) =>
                                               {
                                                   App.ViewModel.Status = string.Empty;
                                               };

            DataObject.AddPastingHandler(SearchBox, OnSearchBoxPaste);
        }

        private void WindowSourceInitialized(object sender, EventArgs e)
        {
            handle = new WindowInteropHelper(this).Handle;

            this.Width = App.Settings.Width;
            this.Height = App.Settings.Height;
            if (App.Settings.Left == -100 || App.Settings.Top == -100)
            {
                this.Left = SystemParameters.PrimaryScreenWidth / 2 - this.Width / 2;
                this.Top = SystemParameters.PrimaryScreenHeight / 2 - this.Height / 2;
            }
            else
            {
                this.Left = App.Settings.Left;
                this.Top = App.Settings.Top;
            }

            if (App.Settings.CheckUpdates)
                App.ViewModel.CheckForUpdates();
        }

        private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            HookManager.KeyDown -= HookManagerKeyDown;

            App.Settings.Shuffle = ShuffleButton.IsChecked == true;
            App.Settings.Volume = MediaElement.Volume;
        }

        void HookManagerKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (MyAudioList.SelectedIndex == -1 && SearchList.SelectedIndex == -1)
                return;
            switch (e.KeyCode)
            {
                case Keys.MediaPlayPause:
                    App.ViewModel.PlayPause();
                    break;
                case Keys.MediaNextTrack:
                    App.ViewModel.NextAudio();
                    break;
                case Keys.MediaPreviousTrack:
                    App.ViewModel.PrevAudio();
                    break;
                case Keys.MediaStop:
                    App.ViewModel.PlayPause();
                    MediaElement.Stop();
                    break;
            }
        }

        //void MessagesCheckTimerTick(object sender, EventArgs e)
        //{
        //    App.ViewModel.GetUnreadMessagesCount();
        //}

        private void WindowMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && e.GetPosition(this).Y < 38)
            {
                DragMove();
                App.Settings.Left = this.Left;
                App.Settings.Top = this.Top;
            }
        }

        private void MinimizeButtonClick(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        //private void MaximizeButtonClick(object sender, RoutedEventArgs e)
        //{
        //    if (this.WindowState == WindowState.Normal)
        //    {
        //        RootGrid.Margin = new Thickness(0);
        //        this.WindowState = WindowState.Maximized;
        //    }
        //    else
        //    {
        //        RootGrid.Margin = new Thickness(15);
        //        this.WindowState = WindowState.Normal;
        //    }
        //}

        private void CloseButtonClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void PrevButtonClick(object sender, RoutedEventArgs e)
        {
            App.ViewModel.PrevAudio();
        }

        private void PlayPauseButtonClick(object sender, RoutedEventArgs e)
        {
            App.ViewModel.PlayPause();
        }

        private void NextButtonClick(object sender, RoutedEventArgs e)
        {
            App.ViewModel.NextAudio();
        }

        private void ResizeGripMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                NativeMethods.SizeWindow(handle);

                App.Settings.Width = this.Width;
                App.Settings.Height = this.Height;
            }
        }

        private void MyAudioListScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            var sb = e.OriginalSource as ScrollViewer;
            if (sb == null)
                return;

            if (Math.Abs(e.VerticalOffset + e.ViewportHeight - e.ExtentHeight) < 5)
            {
                App.ViewModel.LoadMore(App.Settings.DynamicLoadItemsCount);
            }
        }

        private void SearchBoxKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && SearchBox.Text.Length > 0)
            {
                if (SearchBox.Text.StartsWith("!"))
                {
                    var query = SearchBox.Text.Substring(1, SearchBox.Text.Length - 1);
                    App.ViewModel.SearchForAlbum(query);
                }
                else if (!SearchBox.Text.Contains("&&"))
                    App.ViewModel.Search(SearchBox.Text, App.Settings.FirstLoadItemsCount);
                else
                {
                    var query = SearchBox.Text;
                    string artist = string.Empty;
                    if (query.Contains(":"))
                    {
                        artist = query.Substring(0, query.IndexOf(':'));
                        query = query.Substring(query.IndexOf(':') + 1, query.Length - query.IndexOf(':') - 1);
                    }

                    string[] queries = query.Split(new[] { "&&" }, StringSplitOptions.RemoveEmptyEntries);
                    if (!string.IsNullOrEmpty(artist))
                    {
                        for (int i = 0; i < queries.Length; i++)
                            queries[i] = artist + " " + queries[i];
                    }
                    App.ViewModel.SearchMany(queries);
                }

                SearchIcon.Source = Application.Current.Resources["CancelIcon"] as BitmapImage;
            }
        }

        private void SearchListScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            var sb = e.OriginalSource as ScrollViewer;
            if (sb == null)
                return;

            if (Math.Abs(e.VerticalOffset + e.ViewportHeight - e.ExtentHeight) < 5)
            {
                App.ViewModel.SearchMore(App.Settings.DynamicLoadItemsCount);
            }
        }

        private void SearchBoxGotFocus(object sender, RoutedEventArgs e)
        {
            if (SearchBox.Text == Properties.Resources.Search)
                SearchBox.Text = "";
        }

        private void SearchBoxLostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(SearchBox.Text))
                SearchBox.Text = Properties.Resources.Search;
        }


        private void ThumbPrevButtonClick(object sender, EventArgs e)
        {
            App.ViewModel.PrevAudio();
        }

        private void ThumbPlayButtonClick(object sender, EventArgs e)
        {
            App.ViewModel.PlayPause();
        }

        private void ThumbNextButtonClick(object sender, EventArgs e)
        {
            App.ViewModel.NextAudio();
        }

        private void LikeButtonClick(object sender, RoutedEventArgs e)
        {
            App.ViewModel.LikeDislike();
        }

        private void SearchIconMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (SearchList.Items.Count > 0)
            {
                App.ViewModel.SearchResults.Clear();
                SearchIcon.Source = Application.Current.Resources["SearchIcon"] as BitmapImage;
                SearchBox.Text = Properties.Resources.Search;
            }
        }

        private void RemoveItemClick(object sender, RoutedEventArgs e)
        {
            if (MyAudioList.SelectedIndex < 0)
                return;
            App.ViewModel.DeleteAudio((VkAudio)MyAudioList.SelectedItem);
        }

        private void AddItemClick(object sender, RoutedEventArgs e)
        {
            if (SearchList.SelectedIndex < 0)
                return;
            App.ViewModel.AddAudio((VkAudio)SearchList.SelectedItem);
        }

        private void ThumbShuffleButtonClick(object sender, EventArgs e)
        {
            App.ViewModel.Shuffle = !App.ViewModel.Shuffle;
        }

        private void MyAudioListSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (MyAudioList.SelectedIndex > -1)
                App.ViewModel.SearchSelectedIndex = -1;
        }

        private void SearchListSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (SearchList.SelectedIndex > -1)
                App.ViewModel.MyAudioSelectedIndex = -1;
        }

        private void MeridianButtonClick(object sender, RoutedEventArgs e)
        {
            if (SettingsHost.Visibility == Visibility.Collapsed)
            {
                SettingsHost.Visibility = Visibility.Visible;
                var settingsView = new SettingsView();
                settingsView.Closed += SettingsViewClosed;
                SettingsHost.Children.Add(settingsView);
            }
            else
            {
                CloseSettings();
            }
        }

        void SettingsViewClosed(object sender, EventArgs e)
        {
            ((SettingsView)sender).Closed -= SettingsViewClosed;
            CloseSettings();

        }

        void CloseSettings()
        {
            SettingsHost.Children.Clear();
            SettingsHost.Visibility = Visibility.Collapsed;
        }

        private void MiniModeButtonClick(object sender, RoutedEventArgs e)
        {
            this.Hide();
            miniView = new MiniView();
            miniView.Closed += MiniViewClosed;
            miniView.Restore += MiniViewRestore;

            miniView.Left = this.Left + this.Width / 2;
            miniView.Top = this.Top + this.Height / 2;
            miniView.Show();
        }

        void MiniViewRestore(object sender, EventArgs e)
        {
            miniView.Closed -= MiniViewClosed;
            miniView.Restore -= MiniViewRestore;

            miniView.Close();
            this.Show();
        }

        void MiniViewClosed(object sender, EventArgs e)
        {
            this.Close();
        }

        private void ProgressSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (MediaElement.IsBuffering)
                return;
            App.ViewModel.Position = TimeSpan.FromSeconds(ProgressSlider.Value);
        }

        private void SearchListTargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {
            if (SearchList.Items.Count > 0)
            {
                var scroll = VisualTreeHelper.GetChild(SearchList, 0) as ScrollViewer;
                if (scroll != null)
                    scroll.ScrollToHome();
            }
        }

        private void OnSearchBoxPaste(object sender, DataObjectPastingEventArgs e)
        {
            if (!e.DataObject.GetDataPresent(DataFormats.UnicodeText, true)) return;
            var paste = Clipboard.GetData(DataFormats.UnicodeText) as string;
            if (paste == null)
                return;
            paste = paste.Replace("\r\n", " && ").Trim();
            paste = StringHelper.RemoveTimeStamp(paste);
            Clipboard.SetData(DataFormats.UnicodeText, paste);
        }

        private void LeftHideItemClick(object sender, RoutedEventArgs e)
        {
            LeftColumn.Width = new GridLength(0);
            RightRestoreItem.Visibility = Visibility.Visible;
            LeftHideItem.Visibility = Visibility.Collapsed;
            RightHideItem.Visibility = Visibility.Collapsed;
        }

        private void LeftRestoreItemClick(object sender, RoutedEventArgs e)
        {
            RightColumn.Width = new GridLength(1, GridUnitType.Star);
            RightRestoreItem.Visibility = Visibility.Collapsed;
            LeftRestoreItem.Visibility = Visibility.Collapsed;
            LeftHideItem.Visibility = Visibility.Visible;
            RightHideItem.Visibility = Visibility.Visible;
        }

        private void RightHideItemClick(object sender, RoutedEventArgs e)
        {
            RightColumn.Width = new GridLength(0);
            LeftRestoreItem.Visibility = Visibility.Visible;
            RightHideItem.Visibility = Visibility.Collapsed;
            LeftHideItem.Visibility = Visibility.Collapsed;
        }

        private void RightRestoreItemClick(object sender, RoutedEventArgs e)
        {
            LeftColumn.Width = new GridLength(1, GridUnitType.Star);
            LeftRestoreItem.Visibility = Visibility.Collapsed;
            RightRestoreItem.Visibility = Visibility.Collapsed;
            RightHideItem.Visibility = Visibility.Visible;
            LeftHideItem.Visibility = Visibility.Visible;
        }

        private void MyAudioListKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control)
            {
                Clipboard.SetData(DataFormats.UnicodeText, ((VkAudio)MyAudioList.SelectedItem).Artist + " - " + ((VkAudio)MyAudioList.SelectedItem).Title);
            }
        }

        private void SearchListKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control)
            {
                Clipboard.SetData(DataFormats.UnicodeText, ((VkAudio)SearchList.SelectedItem).Artist + " - " + ((VkAudio)SearchList.SelectedItem).Title);
            }
        }
    }
}
